<dom-module id="grid-tree-demos">
  <template>
    <style include="vaadin-component-demo-shared-styles">
      :host {
        display: block;
      }
    </style>

    <h3>Tree Column Helper and Hierarchical Data</h3>
    <p>
      Use <code>&lt;vaadin-grid-tree-column&gt;</code> to create a column with tree toggle UI controls in the body cells.
      The property <code>itemHasChildrenPath</code> is used for determining whether an individual item has child items
      or if it's a leaf node instead.
    </p>
    <p>
      <strong>NOTE: Hierarchical data only works with a <code>dataProvider</code>.
        Using <code>items</code> will not work properly with a tree grid.</strong>
    </p>
    <p>
      <strong>NOTE: You must explicitly import <code>vaadin-grid-tree-column</code> in order to use it.</strong>
    </p>
    <vaadin-demo-snippet id="grid-tree-demos-renderer-data-provider" when-defined="vaadin-grid">
      <template preserve-content>
        <vaadin-grid aria-label="Tree Data Grid Example" data-provider="[[_dataProvider]]">
          <vaadin-grid-tree-column path="name" header="Expense category" item-has-children-path="hasChildren"></vaadin-grid-tree-column>
          <vaadin-grid-column path="uuid" header="Code" width="8em" flex-grow="0"></vaadin-grid-column>
        </vaadin-grid>

        <script>
          window.addDemoReadyListener('#grid-tree-demos-renderer-data-provider', function(document) {
            const grid = document.querySelector('vaadin-grid');
            grid.dataProvider = function(params, callback) {
              // If the data request concerns a tree sub-level, `params` has an additional
              // `parentItem` property that refers to the sub-level's parent item
              const parentUuid = params.parentItem ? params.parentItem.uuid : null;

              // Demo helper API that fetches expenses categories
              Vaadin.GridDemo._getExpensesCategories(parentUuid, function(categories) {
                // Here `categories` is an array consisting of items with the following structure:
                // {
                //   hasChildren: false
                //   name: "Service fees",
                //   uuid: "e78b"
                //   parentUuid: "e789"
                // }
                // This demo uses the `hasChildren` flag as an indicator of the item having child items.
                // The property is used internally by the `<vaadin-grid-tree-column>`.

                // Slice out only the requested items
                const startIndex = params.page * params.pageSize;
                const pageItems = categories.slice(startIndex, startIndex + params.pageSize);
                // Inform grid of the requested tree level's full size
                const treeLevelSize = categories.length;
                callback(pageItems, treeLevelSize);
              });
            };
          });
        </script>
      </template>
    </vaadin-demo-snippet>

    <h3>Tree Toggle Helper</h3>
    <p>
      Use <code>&lt;vaadin-grid-tree-toggle&gt;</code> in the cell content
      to make a tree UI inside a grid. You need to update the <code>expanded</code>,
      <code>level</code>, and <code>leaf</code> properties in your renderer.
    </p>
    <p>
      <strong>NOTE: You must explicitly import <code>vaadin-grid-tree-toggle</code> in order to use it.</strong>
    </p>
    <vaadin-demo-snippet id="grid-tree-demos-tree-toggle" when-defined="vaadin-grid">
      <template preserve-content>
        <vaadin-grid aria-label="Tree Data Grid Example" data-provider="[[_dataProvider]]">
          <vaadin-grid-column header="Expense category"></vaadin-grid-column>
          <vaadin-grid-column path="uuid" header="Code" width="8em" flex-grow="0"></vaadin-grid-column>
        </vaadin-grid>

        <script>
          window.addDemoReadyListener('#grid-tree-demos-tree-toggle', function(document) {
            const grid = document.querySelector('vaadin-grid');
            const column = grid.querySelector('vaadin-grid-column');

            column.renderer = function(root, col, model) {
              let toggler = root.firstElementChild;
              if (!toggler) {
                toggler = window.document.createElement('vaadin-grid-tree-toggle');
                toggler.addEventListener('expanded-changed', function(e) {
                  grid[toggler.expanded ? 'expandItem' : 'collapseItem'](toggler.item);
                });
                root.appendChild(toggler);
              }

              toggler.item = model.item;
              toggler.leaf = !model.item.hasChildren;
              toggler.expanded = model.expanded;
              toggler.level = model.level;
              toggler.textContent = model.item.name;
            };

            grid.dataProvider = function(params, callback) {
              // If the data request concerns a tree sub-level, `params` has an additional
              // `parentItem` property that refers to the sub-level's parent item
              const parentUuid = params.parentItem ? params.parentItem.uuid : null;

              // Demo helper API that fetches expenses categories
              Vaadin.GridDemo._getExpensesCategories(parentUuid, function(categories) {
                // Here `categories` is an array consisting of items with the following structure:
                // {
                //   hasChildren: false
                //   name: "Service fees",
                //   uuid: "e78b"
                //   parentUuid: "e789"
                // }
                // This demo uses the `hasChildren` flag as an indicator of the item having child items.
                // The property is bound to `<vaadin-grid-tree-toggle>`'s `leaf` property in
                // the renderer above.

                // Slice out only the requested items
                const startIndex = params.page * params.pageSize;
                const pageItems = categories.slice(startIndex, startIndex + params.pageSize);
                // Inform grid of the requested tree level's full size
                const treeLevelSize = categories.length;
                callback(pageItems, treeLevelSize);
              });
            };
          });
        </script>
      </template>
    </vaadin-demo-snippet>

    <h3>Tree Using Templates and Polymer Binding</h3>
    <p>
      Use <code>&lt;vaadin-grid-tree-toggle&gt;</code> in the column body
      template to make a tree UI inside a grid. Make sure you have bindings
      for the <code>expanded</code>, <code>level</code>, and <code>leaf</code>
      properties.
    </p>
    <vaadin-demo-snippet id="grid-tree-demos-polymer-template" when-defined="vaadin-grid">
      <template preserve-content>
        <vaadin-grid aria-label="Tree Data Grid Example" data-provider="[[_dataProvider]]">
          <vaadin-grid-column>
            <template class="header">Expense category</template>
            <template>
              <vaadin-grid-tree-toggle
                  leaf="[[!item.hasChildren]]"
                  expanded="{{expanded}}"
                  level="[[level]]">
                [[item.name]]
              </vaadin-grid-tree-toggle>
            </template>
          </vaadin-grid-column>
          <vaadin-grid-column width="8em" flex-grow="0">
            <template class="header">Code</template>
            <template>[[item.uuid]]</template>
          </vaadin-grid-column>
        </vaadin-grid>

        <script>
          window.addDemoReadyListener('#grid-tree-demos-polymer-template', function(document) {
            const grid = document.querySelector('vaadin-grid');
            grid.dataProvider = function(params, callback) {
              // If the data request concerns a tree sub-level, `params` has an additional
              // `parentItem` property that refers to the sub-level's parent item
              const parentUuid = params.parentItem ? params.parentItem.uuid : null;

              // Demo helper API that fetches expenses categories
              Vaadin.GridDemo._getExpensesCategories(parentUuid, function(categories) {
                // Here `categories` is an array consisting of items with the following structure:
                // {
                //   hasChildren: false
                //   name: "Service fees",
                //   uuid: "e78b"
                //   parentUuid: "e789"
                // }
                // This demo uses the `hasChildren` flag as an indicator of the item having child items.
                // The property is bound to `<vaadin-grid-tree-toggle>`'s `leaf` property in
                // the template above.

                // Slice out only the requested items
                const startIndex = params.page * params.pageSize;
                const pageItems = categories.slice(startIndex, startIndex + params.pageSize);
                // Inform grid of the requested tree level's full size
                const treeLevelSize = categories.length;
                callback(pageItems, treeLevelSize);
              });
            };
          });
        </script>
      </template>
    </vaadin-demo-snippet>

  </template>
  <script src="tree-data.js"></script>
  <script>
    class GridTreeDemos extends DemoReadyEventEmitter(GridDemo(Polymer.Element)) {
      static get is() {
        return 'grid-tree-demos';
      }

      ready() {
        super.ready();

        window.Vaadin = window.Vaadin || {};
        window.Vaadin.GridDemo = window.Vaadin.GridDemo || {};
        window.Vaadin.GridDemo._getExpensesCategories = function(parentUuid, callback) {
          callback(window.Vaadin.GridDemo._treeData.filter(function(expense) {
            if (parentUuid) {
              return expense.parentUuid === parentUuid;
            } else {
              return !expense.parentUuid;
            }
          }));
        };
      }
    }
    customElements.define(GridTreeDemos.is, GridTreeDemos);
  </script>
</dom-module>
